/**
 @file cpu.c
 @brief The cpu workload.
 @description Contains all functions used by the cpu workload.
*/

#include <stdio.h>
#include <pthread.h>
#include "resource_model.h"
#include "cpu.h"
#include "random.h"
#include "scheduler.h"
#include "generator.h"

/** Stop a running CPU job. */
void cancel_cpu_workload(void *);

/** Utilize the CPU. */
void *workload_cpu(void *);

/** Spawn a CPU job, schedule its termination and the next job. */
void create_cpu_workload(void *);

/** Set up the utilize mode. */
mode * setup_utilize(cJSON *);

/** Hash table that stores all the CPU workload's modes. */
mode_definition_list * cpu_modes[HASHSIZE];

resource_model * setup_cpu(cJSON *json) {
  install_mode(cpu_modes, "u", setup_utilize);
  cJSON *distribution = cJSON_GetObjectItem(json, "distribution");
  setup_rng("cpu_arrival", distribution);
  resource_model *model = malloc(sizeof(resource_model));
  model->birth = create_cpu_workload;
  model->state = NULL;
  model->modes = initialize_modes(cpu_modes,json);
  model->cnt_modes = count_modes(json);
  return model;
}

void create_cpu_workload(void *args) 
{  
  pthread_t *thread = spawn_job((resource_model *) args);
  schedule_event(ms_from_now(get_random_number("cpu_arrival")), create_cpu_workload, args);
  schedule_event(ms_from_now(get_random_number("u_length")), cancel_cpu_workload, (void *)thread);
}

void * workload_cpu(void *args) {
  unsigned int x = 0;
  while(1) {  
    if(++x%500==0) {
      pthread_testcancel();
    }  
  }
}

void cancel_cpu_workload(void *args) {
  pthread_t *t = (pthread_t *)args;
  pthread_cancel(*t);
  free(t);
}

mode * setup_utilize(cJSON *json) {
  setup_rng("u_length", cJSON_GetObjectItem(json, "length"));
  return new_mode("u",workload_cpu,json);
}
